package com.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.common.dto.CommentDTO;
import com.common.mapper.CommentMapper;
import com.common.model.Comment;
import com.common.query.CommentQueryParam;
import com.common.service.CommentService;
import com.util.CombineBeansUtil;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;

@Service
public class CommentServiceImpl implements CommentService {

    private CommentMapper commentMapper;

    public CommentServiceImpl(CommentMapper commentMapper) {
        this.commentMapper = commentMapper;
    }

    @Override
    public List<CommentDTO> selectPageByArticleId(Integer page, Integer pageSize, Long articleId, CommentQueryParam queryParam) {
        return getCommentDTOS(page, pageSize, articleId, queryParam);
    }

    @Override
    public List<CommentDTO> selectPageByArticleId(Integer page, Integer pageSize, Long articleId) {

        CommentQueryParam cm = new CommentQueryParam();
        cm.setOrder("create_time");
        cm.setSort("desc");

        return getCommentDTOS(page, pageSize, articleId, cm);
    }

    @Override
    public Integer countByArticleId(Long articleId) {
        QueryWrapper<Comment> qw = new QueryWrapper<>();
        qw.eq("article_id", articleId);
        return commentMapper.selectCount(qw);
    }

    private List<CommentDTO> getCommentDTOS(Integer page, Integer pageSize, Long articleId, CommentQueryParam queryParam) {

        List<CommentDTO> commentDTOS = getTreeCommentsAndReply(null, articleId, queryParam);

        Integer start = (page - 1) * pageSize;
        int end = start + pageSize;

        if (commentDTOS.size() >= start) {
            if (commentDTOS.size() >= end) {
                return commentDTOS.subList(start, end);
            } else {
                return commentDTOS.subList(start, commentDTOS.size());
            }
        } else {
            return null;
        }
    }

    /**
     * 递归查询Comment 下面的回复
     *
     * @param parentCommentId 父级评论ID
     * @param queryParam      查询参数
     */
    private List<CommentDTO> getTreeCommentsAndReply(Long parentCommentId, Long articleId, CommentQueryParam queryParam) {

        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        boolean asc = queryParam.getSort().equals("asc");
        queryWrapper.orderBy(true, asc, queryParam.getOrder());
        queryWrapper.eq("article_id", articleId);
        //寻找 parent_comment_id 为空的数据 构建树形结构
        if (parentCommentId == null) {
            queryWrapper.isNull("parent_comment_id");
        } else {
            queryWrapper.eq("parent_comment_id", parentCommentId);
        }

        List<Comment> comments = commentMapper.selectList(queryWrapper);
        List<CommentDTO> commentDTOS = new LinkedList<>();
        comments.forEach(comment -> {
            try {
                CommentDTO commentDTO = changeEntityToDTO(comment);
                commentDTO.setReplay(getTreeCommentsAndReply(commentDTO.getCommentId(), articleId, queryParam));
                commentDTOS.add(commentDTO);
            } catch (InvocationTargetException | IllegalAccessException e) {
                e.printStackTrace();
            }
        });

        return commentDTOS;
    }


    /**
     * 将 Entity 转换成 DTO
     */
    private CommentDTO changeEntityToDTO(Comment comment) throws InvocationTargetException, IllegalAccessException {
        CommentDTO commentDTO = new CommentDTO();
        CombineBeansUtil.combineBean(comment, commentDTO);
        return commentDTO;
    }
}
